home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Sample.bin / RoundButton.java < prev    next >
Text File  |  1998-09-15  |  5KB  |  196 lines

  1. /*
  2.  * @(#)RoundButton.java    1.1 98/07/18
  3.  *
  4.  * Copyright (c) 1995-1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  */
  7. package actual;
  8.  
  9. import java.applet.*;
  10. import java.lang.*;
  11. import java.util.*;
  12. import java.awt.*;
  13. import java.awt.event.*;
  14.  
  15. /**
  16.  * RoundButton - a class that produces a lightweight button.
  17.  *
  18.  * Lightweight components can have "transparent" areas, meaning that
  19.  * you can see the background of the container behind these areas.
  20.  *
  21.  */
  22. public class RoundButton extends Component {
  23.  
  24.   ActionListener actionListener;     // Post action events to listeners
  25.   String label;                      // The Button's text
  26.   protected boolean pressed = false; // true if the button is detented.
  27.   
  28.   
  29.   /**
  30.    * Constructs a RoundButton with no label.
  31.    */
  32.   public RoundButton() {
  33.       this("");
  34.   }
  35.  
  36.   /**
  37.    * Constructs a RoundButton with the specified label.
  38.    * @param label the label of the button
  39.    */
  40.   public RoundButton(String label) {
  41.       this.label = label;
  42.       enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  43.   }
  44.  
  45.   /**
  46.    * gets the label
  47.    * @see setLabel
  48.    */
  49.   public String getLabel() {
  50.       return label;
  51.   }
  52.   
  53.   /**
  54.    * sets the label
  55.    * @see getLabel
  56.    */
  57.   public void setLabel(String label) {
  58.       this.label = label;
  59.       invalidate();
  60.       repaint();
  61.   }
  62.   
  63.   /**
  64.    * paints the RoundButton
  65.    */
  66.   public void paint(Graphics g) {
  67.       int s = Math.min(getSize().width - 1, getSize().height - 1);
  68.       
  69.       // paint the interior of the button
  70.       if(pressed) {
  71.       g.setColor(getBackground().darker().darker());
  72.       } else {
  73.       g.setColor(getBackground());
  74.       }
  75.       g.fillArc(0, 0, s, s, 0, 360);
  76.       
  77.       // draw the perimeter of the button
  78.       g.setColor(getBackground().darker().darker().darker());
  79.       g.drawArc(0, 0, s, s, 0, 360);
  80.       
  81.       // draw the label centered in the button
  82.       Font f = getFont();
  83.       if(f != null) {
  84.       FontMetrics fm = getFontMetrics(getFont());
  85.       g.setColor(getForeground());
  86.       g.drawString(label,
  87.                s/2 - fm.stringWidth(label)/2,
  88.                s/2 + fm.getMaxDescent());
  89.       }
  90.   }
  91.   
  92.   /**
  93.    * The preferred size of the button. 
  94.    */
  95.   public Dimension getPreferredSize() {
  96.       Font f = getFont();
  97.       if(f != null) {
  98.       FontMetrics fm = getFontMetrics(getFont());
  99.       int max = Math.max(fm.stringWidth(label) + 40, fm.getHeight() + 40);
  100.       return new Dimension(max, max);
  101.       } else {
  102.       return new Dimension(100, 100);
  103.       }
  104.   }
  105.   
  106.   /**
  107.    * The minimum size of the button. 
  108.    */
  109.   public Dimension getMinimumSize() {
  110.       return new Dimension(100, 100);
  111.   }
  112.  
  113.   /**
  114.    * Adds the specified action listener to receive action events
  115.    * from this button.
  116.    * @param listener the action listener
  117.    */
  118.    public void addActionListener(ActionListener listener) {
  119.        actionListener = AWTEventMulticaster.add(actionListener, listener);
  120.        enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  121.    }
  122.  
  123.    /**
  124.     * Removes the specified action listener so it no longer receives
  125.     * action events from this button.
  126.     * @param listener the action listener
  127.     */
  128.    public void removeActionListener(ActionListener listener) {
  129.        actionListener = AWTEventMulticaster.remove(actionListener, listener);
  130.    }
  131.  
  132.   /**
  133.    * Determine if click was inside round button.
  134.    */
  135.    public boolean contains(int x, int y) {
  136.        int mx = getSize().width/2;
  137.        int my = getSize().height/2;
  138.        return (((mx-x)*(mx-x) + (my-y)*(my-y)) <= mx*mx);
  139.    }
  140.    
  141.    /**
  142.     * Paints the button and distribute an action event to all listeners.
  143.     */
  144.    public void processMouseEvent(MouseEvent e) {
  145.        Graphics g;
  146.        switch(e.getID()) {
  147.           case MouseEvent.MOUSE_PRESSED:
  148.         // render myself inverted....
  149.         pressed = true;
  150.  
  151.             // Repaint might flicker a bit. To avoid this, you can use
  152.             // double buffering (see the Gauge example).
  153.         repaint(); 
  154.         break;
  155.           case MouseEvent.MOUSE_RELEASED:
  156.         if(actionListener != null) {
  157.            actionListener.actionPerformed(new ActionEvent(
  158.            this, ActionEvent.ACTION_PERFORMED, label));
  159.         }
  160.         // render myself normal again
  161.         if(pressed == true) {
  162.         pressed = false;
  163.  
  164.                 // Repaint might flicker a bit. To avoid this, you can use
  165.                 // double buffering (see the Gauge example).
  166.         repaint();
  167.         }
  168.         break;
  169.           case MouseEvent.MOUSE_ENTERED:
  170.  
  171.         break;
  172.           case MouseEvent.MOUSE_EXITED:
  173.         if(pressed == true) {
  174.         // Cancel! Don't send action event.
  175.         pressed = false;
  176.  
  177.                 // Repaint might flicker a bit. To avoid this, you can use
  178.                 // double buffering (see the Gauge example).
  179.         repaint();
  180.  
  181.         // Note: for a more complete button implementation,
  182.         // you wouldn't want to cancel at this point, but
  183.         // rather detect when the mouse re-entered, and
  184.         // re-highlight the button. There are a few state
  185.         // issues that that you need to handle, which we leave
  186.         // this an an excercise for the reader (I always
  187.         // wanted to say that!)
  188.         }
  189.         break;
  190.        }
  191.        super.processMouseEvent(e);
  192.    }
  193.    
  194. }
  195.  
  196.